#pragma once
namespace lzf
{
	template<class T>
	struct list_node
	{
		list_node<T>* _next;
		list_node<T>* _prev;
		T  _date;


		list_node(const T& x)
			:_next(nullprt)
			,_prev(nullprt)
			,_date(x)
		{}
	};

	template<class T>
	class _list_iterator
	{
		typedef list_node<T>  node;
		node* _pnode;

		_list_iterator(node* p)
			:_pnode(p)
		{}

		T& operate* ()
		{
			return _pnode->_date;
		}

		_list_iterator<T>& opreate++()
		{
			_pnode = _pnode->next;
			return *this;
		}

		_list_iterator<T>& operate--()
		{
			_pnode = _pnode->next;
			return *this;
		}

		bool operate != (const _list_iterator<T>& it)
		{
			return _pnode != it;
		}
	};

	template<class T>
	class _list_const_iterator
	{
		typedef list_node<T>  node;
		node* _pnode;

		_list_const_iterator(node* p)
			:_pnode(p)
		{}

		const T& operate* ()
		{
			return _pnode->_date;
		}

		_list_const_iterator<T>& opreate++()
		{
			_pnode = _pnode->next;
			return *this;
		}

		_list_const_iterator<T>& operate--()
		{
			_pnode = _pnode->next;
			return *this;
		}

		bool operate != (const _list_iterator<T>&it)
		{
			return _pnode != it;
		}
	};

	template <class T>
	class list
	{
		typedef list_node<T> node;
		typedef _list_iterator<T> iterator;
		typedef  _list_const_iterator const_iterator;
		
		iterator begin()
		{
			return  iterator(_head->_next);
		}

		iterator end()
		{
			return iterator(_head);
		}

		const_iterator begin()
		{
			return  const_iterator(_head->_next);
		}

		const_iterator end()
		{
			return const_iterator(_head);
		}

		void empty_initialize()
		{
			_head = new node(T());
			_head->_next = _head;
			_head->_prev = _head;
		}

		list()
		{
			empty_initialize();
		}

		list(const list<T>& It)
		{
			empty_initialize();
			for (const auto& e : It)
			{
				push_back(e);
			}
		}

		void push_back(constn T& x)
		{
			node* newnode = new node(x);
			//node* tail=_head->prev;
			newnode->_next = _head;
			newnode->_prev = _head->_prev;
			_head->_prev->_next = newnode;
			_head->_prev = newnode;
		}
	private:
		node* _head;
	};


}